#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> 
#include <stdlib.h>
#include <assert.h>
#include "app_platform/cntl_info.h"
#include "employeeao.h"


using namespace erp::employee::ao;

CPP_SELF_DEFINE_START
/**
*  请在这里增加自定义的成员变量和函数及其他内容，否则无法合并代码
**/
#include "employeeao_enum.h"
#include "erp/comm/erp_errno_define.h"
#include "c2cplatform/library/string/string_helper.h"
#include "erp/comm/erp_macro_define.h"
#include "erp/gis/comm/erp_gis_define.h"
#include "erp/employee/dao/employeedao_stub4app_allinone.h"
#include "erp/employee/to/EmployeeFilterTo.h"
#include "erp/employee/to/EmployeeTo.h"

using namespace c2cent::library::wtimeelf;
using namespace c2cent::library::wwlog;
using namespace c2cplatform::library::string;
using namespace erp::comm;
using namespace erp::gis::comm;
using namespace erp::employee::dao;
using namespace erp::employee::to;

CItilGroup CEmployeeAo::s_oGetEmployee_Group(GETEMPLOYEE_REQ ,GETEMPLOYEE_ERR,GETEMPLOYEE_RSP,GETEMPLOYEE_DEF);
CItilGroup CEmployeeAo::s_oAddEmployee_Group(ADDEMPLOYEE_REQ ,ADDEMPLOYEE_ERR,ADDEMPLOYEE_RSP,ADDEMPLOYEE_DEF);
CPP_SELF_DEFINE_END

/**
 *构建函数
 */
CEmployeeAo::CEmployeeAo(enum DeployMethod method)
{
}

/**
 *析构函数
 */
CEmployeeAo::~CEmployeeAo()
{
}


/**
 *每一次服务请求时，container都会调用此方法来清空数据
 */
void  CEmployeeAo::Reset()
{
	m_dwOperatorUin=0;
	m_dwSceneId=0;
	m_strMachineKey="";
	m_strSource="";
}


int  CEmployeeAo::Initialize(IUserDefineCntl* pCntl)
{
	int iRetCode = 0;

    uint32_t dwLogSwitch=WLOG_OPEN|WLOG_KEY_OPEN|WLOG_ERR_OPEN;
    uint32_t dwCanLogRemote = 0;
    uint32_t dwPageSizeLimit=50;
    std::string strLogModule="ao_joms";
    std::string strValidProperty="0,1,2";

    std::cout<<"File:"<<__FILE__<<" Complie Date: "<<__DATE__<<" "<<__TIME__<<std::endl;

    GetUintConfig(LogSwitch);
    GetStringConfig(LogModule);
    GetStringConfig(ValidProperty);
    GetUintConfig(CanLogRemote);
    GetUintConfig(PageSizeLimit);

    s_dwPageSizeLimit=dwPageSizeLimit;

    std::set<std::string> setItem;

    SplitStringIntoSet(strValidProperty.c_str(),",",setItem);

    for(std::set<std::string>::const_iterator it=setItem.begin();it!=setItem.end();it++)
    {
    	s_bitsetValidPropertyBit.set(strtoull((*it).c_str(),NULL,10));
    }

    // 初始化日志
    if( C2C_WWLOG->QuickInitForAPP2(strLogModule.c_str(),B2B2CWW_LOG_APP_FILE_PATH, dwCanLogRemote, dwLogSwitch)!= 0)
    {
            std::cerr << "C2C_WWLOG->QuickInitForAPP2 Failed" << std::endl;
            return -1;
    }
    C2C_WW_LOG("C2C_WWLOG->QuickInitForAPP2 OK!");

	return iRetCode;
}


/**
 *
 *  根据ID获取员工信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param EmployeeFilterPo employeeFilter: 过滤器，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map employees: 员工信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CEmployeeAo::GetEmployeeById(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				const erp::employee::po::CEmployeeFilterPo& oEmployeeFilter,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::map<uint32_t,erp::employee::po::CEmployeePo >& mapEmployees,
				std::string& strOutReserve
	)
{
	int iRetCode = 0;

    m_strMachineKey=strMachineKey;
    m_strSource=strSource;
    m_dwSceneId=dwSceneId;
    m_dwOperatorUin=rCntlInfo.getOperatorUin();

    C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u", __FUNCTION__,
                    m_dwOperatorUin, strMachineKey.c_str(), strSource.c_str(), dwSceneId);

    //打印性能日志的同时进行接口的itil上报
    C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&s_oGetEmployee_Group);

    iRetCode=CheckCommPara();
    if(iRetCode!=0)
    {
    	C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
    	return iRetCode;
    }

    iRetCode=CheckEmployeeFilter(oEmployeeFilter);
    if(iRetCode!=0)
    {
    	C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
    	return iRetCode;
    }

    CEmployeeDaoStub4App oStub;

    erp::employee::ddo::CEmployeeFilterDdo oEmployeeFilterDdo;
    std::map<uint32_t,erp::employee::ddo::CEmployeeDdo> mapEmployeesDdo;

    CEmployeeFilterPoConvCEmployeeFilterDdo::Conv_CEmployeeFilterPo_To_CEmployeeFilterDdo(oEmployeeFilter,oEmployeeFilterDdo);

    iRetCode = oStub.GetEmployeeById(
    		rCntlInfo,
    		m_strMachineKey,
    		m_strSource,
    		m_dwSceneId,
    		oEmployeeFilterDdo,
    		strInReserve,
    		strErrmsg,
    		mapEmployeesDdo,
    		strOutReserve);
	if(iRetCode!=0)
	{
	    C2C_WW_LOG_ERR(iRetCode,"GetEmployeeById Failed! SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u ErrMsg:%s",
	    		m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId,strErrmsg.c_str());
	    C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return iRetCode;
	}

	std::map<uint32_t,erp::employee::ddo::CEmployeeDdo>::const_iterator it=mapEmployeesDdo.begin();
	std::map<uint32_t,erp::employee::ddo::CEmployeeDdo>::const_iterator itEnd=mapEmployeesDdo.end();
    for(;it!=itEnd;it++)
    {
    	erp::employee::po::CEmployeePo oEmployeePo;

    	CEmployeePoConvCEmployeeDdo::Conv_CEmployeeDdo_To_CEmployeePo(it->second,oEmployeePo);

    	mapEmployees[oEmployeePo.GetEmployeeId()]=oEmployeePo;
    }

    C2C_WW_LOG("GetEmployeeById Passed! Size:%zu SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u ErrMsg:%s",
    		mapEmployeesDdo.size(),m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId,strErrmsg.c_str());

	return iRetCode;
}

/**
 *
 *  写入员工信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景id，必填   [in]
 *@param EmployeePo employee: 员工信息列表，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param EmployeePo employeeBack: 员工信息列表，必填  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t CEmployeeAo::AddEmployee(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				const erp::employee::po::CEmployeePo& oEmployee,
				const std::string& strInReserve,
				std::string& strErrmsg,
				erp::employee::po::CEmployeePo& oEmployeeBack,
				std::string& strOutReserve
	)
{
		int32_t iRetCode = 0;
		//TODO:业务代码
	    m_strMachineKey=strMachineKey;
	    m_strSource=strSource;
	    m_dwSceneId=dwSceneId;
	    m_dwOperatorUin=rCntlInfo.getOperatorUin();


	    C2C_WW_LOG("GetAReq %s OpUin:%u MachineKey:%s Source:%s SceneId:%u", __FUNCTION__,
	                    m_dwOperatorUin, strMachineKey.c_str(), strSource.c_str(), dwSceneId);

	    //打印性能日志的同时进行接口的itil上报
		C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&s_oAddEmployee_Group);

		iRetCode=CheckCommPara();
		if(iRetCode!=0)
		{
			C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
			return iRetCode;
		}

		iRetCode=CheckEmployee(oEmployee);
		if(iRetCode!=0)
		{
		    C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		    return iRetCode;
		}

	    CEmployeeDaoStub4App oStub;
	    erp::employee::ddo::CEmployeeDdo oEmployeeddo;
	    erp::employee::ddo::CEmployeeDdo oEmployeeddoBack;
	    erp::employee::ddo::CEmployeeFilterDdo oEmployeeFilterDdo;
	    std::map<uint32_t,erp::employee::ddo::CEmployeeDdo>  mapEmployeesDdo;
	    std::set<uint32_t> idList;

	    CEmployeePoConvCEmployeeDdo::Conv_CEmployeePo_To_CEmployeeDdo(oEmployee,oEmployeeddo);

	    iRetCode=oStub.AddEmployee(rCntlInfo,m_strMachineKey,m_strSource,m_dwSceneId,oEmployeeddo,
	    		strInReserve,strErrmsg,oEmployeeddoBack,strOutReserve);

		if(iRetCode!=0)
		{
		    C2C_WW_LOG_ERR(iRetCode,"AddEmployee Failed! ID:%u SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u ErrMsg:%s",
		    		oEmployee.GetEmployeeId(),m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId,strErrmsg.c_str());
		    C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
			return iRetCode;
		}

		idList.insert(oEmployee.GetEmployeeId());
		iRetCode = oStub.GetEmployeeById(
		    		rCntlInfo,
		    		m_strMachineKey,
		    		m_strSource,
		    		m_dwSceneId,
		    		oEmployeeFilterDdo,
		    		strInReserve,
		    		strErrmsg,
		    		mapEmployeesDdo,
		    		strOutReserve);

		if(iRetCode!=0)
		{
			C2C_WW_LOG_ERR(iRetCode,"GetEmployee Failed! ID:%u SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u ErrMsg:%s",
				    		oEmployee.GetEmployeeId(),m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId,strErrmsg.c_str());
			C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
			return iRetCode;
		}
		oEmployeeddoBack=mapEmployeesDdo[oEmployee.GetEmployeeId()];

		CEmployeePoConvCEmployeeDdo::Conv_CEmployeeDdo_To_CEmployeePo(oEmployeeddoBack,oEmployeeBack);

	    C2C_WW_LOG("AddEmployee Passed! ID:%u SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		oEmployeeddoBack.GetEmployeeId(),m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);


	    return iRetCode;
}



int32_t CEmployeeAo::CheckCommPara()
{
	int32_t iRetCode = 0;

	if(m_strMachineKey.empty())
	{
		iRetCode=ERR_ERP_COMMON_MACHINEKEY_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"MachineKey Error! MachineKey:%s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_strMachineKey.c_str(),m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(m_strSource.empty())
	{
		iRetCode=ERR_ERP_COMMON_SOURCE_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"Source Error! Source:%s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_strSource.c_str(),m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(m_dwSceneId==0)
	{
		iRetCode=ERR_ERP_COMMON_SCENEID_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"SceneId Error! SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	return iRetCode;
}

int32_t CEmployeeAo::CheckEmployeeFilter(const erp::employee::po::CEmployeeFilterPo& oEmployeeFilter)
{
	int32_t iRetCode = 0;

	if(oEmployeeFilter.IsPageSizeSet()&&s_dwPageSizeLimit<oEmployeeFilter.GetPageSize())
	{
		iRetCode=ERR_ERP_EMPLOYEE_PAGESIZE;
	    C2C_WW_LOG_ERR(iRetCode,"PageSize Error! PageSize:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		oEmployeeFilter.GetPageSize(),s_dwPageSizeLimit,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployeeFilter.IsIdListSet()&&s_dwPageSizeLimit<oEmployeeFilter.GetIdList().size())
	{
		iRetCode=ERR_ERP_EMPLOYEE_PAGESIZE;
	    C2C_WW_LOG_ERR(iRetCode,"IdListSize Error! IdListSize:%zu MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		oEmployeeFilter.GetIdList().size(),s_dwPageSizeLimit,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployeeFilter.IsOrderTypeSet()&&
			(oEmployeeFilter.GetOrderType()>ORDERTYPE_MAX))
	{
		iRetCode=ERR_ERP_EMPLOYEE_ORDERTYPE;
	    C2C_WW_LOG_ERR(iRetCode,"OrderType Error! OrderType:%u MinLimit:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		oEmployeeFilter.GetOrderType(),ORDERTYPE_MIN,ORDERTYPE_MAX,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployeeFilter.IsEmployeeEnglishNameSet()&&LENGTH_ENGLISHNAME<oEmployeeFilter.GetEmployeeEnglishName().size())
	{
		iRetCode=ERR_ERP_EMPLOYEE_ENGLISHNAMESIZE;
		C2C_WW_LOG_ERR(iRetCode,"EnglishName Error! EnglishName:%s EnglishNameLimitSize:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
			   oEmployeeFilter.GetEmployeeEnglishName().c_str(),LENGTH_ENGLISHNAME,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployeeFilter.IsEmployeeNameSet()&&LENGTH_NAME<oEmployeeFilter.GetEmployeeName().size())
	{
		iRetCode=ERR_ERP_EMPLOYEE_NAMESIZE;
		C2C_WW_LOG_ERR(iRetCode,"Name Error! Name:%s NameLimitSize:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				  oEmployeeFilter.GetEmployeeName().c_str(),LENGTH_NAME,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployeeFilter.IsEmployeeStatusSet()&&
				(*oEmployeeFilter.GetEmployeeStatus().rbegin()>STATUS_MAX))
	{
		iRetCode=ERR_ERP_EMPLOYEE_STATUS;
		C2C_WW_LOG_ERR(iRetCode,"STATUS Error! STATUS:%u MinLimit:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				*oEmployeeFilter.GetEmployeeStatus().rbegin(),STATUS_MIN,STATUS_MAX,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}



	return iRetCode;
}

int32_t CEmployeeAo::CheckEmployee(const erp::employee::po::CEmployeePo& oEmployee)
{
	int32_t iRetCode = 0;

	if(oEmployee.IsEmployeeEnglishNameSet()&&LENGTH_ENGLISHNAME<oEmployee.GetEmployeeEnglishName().size())
	{
		iRetCode=ERR_ERP_EMPLOYEE_ENGLISHNAMESIZE;
		C2C_WW_LOG_ERR(iRetCode,"EnglishName Error! EnglishName:%s EnglishNameLimitSize:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeeEnglishName().c_str(),LENGTH_ENGLISHNAME,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployee.IsEmployeeNameSet()&&LENGTH_NAME<oEmployee.GetEmployeeName().size())
	{
		iRetCode=ERR_ERP_EMPLOYEE_NAMESIZE;
		C2C_WW_LOG_ERR(iRetCode,"Name Error! Name:%s NameLimitSize:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeeName().c_str(),LENGTH_NAME,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployee.IsEmployeeSexSet()&&oEmployee.GetEmployeeSex()>SEX_MAX)
	{
		iRetCode=ERR_ERP_EMPLOYEE_SEX;
		C2C_WW_LOG_ERR(iRetCode,"SEX Error! Sex:%u MinLimit:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeeSex(),SEX_MIN,SEX_MAX,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployee.IsEmployeeStatusSet()&&oEmployee.GetEmployeeStatus()>STATUS_MAX)
	{
		iRetCode=ERR_ERP_EMPLOYEE_STATUS;
		C2C_WW_LOG_ERR(iRetCode,"STATUS Error! STATUS:%u MinLimit:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeeStatus(),STATUS_MIN,STATUS_MAX,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(oEmployee.IsEmployeeTypeSet()&&oEmployee.GetEmployeeType()>TYPE_MAX)
	{
		iRetCode=ERR_ERP_EMPLOYEE_TYPE;
		C2C_WW_LOG_ERR(iRetCode,"TYPE Error! Type:%u MinLimit:%u MaxLimit:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeeStatus(),TYPE_MIN,TYPE_MAX,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if((oEmployee.GetEmployeePropertyInclude()&(~s_bitsetValidPropertyBit)).to_ulong()>0)
	{
		iRetCode=ERR_ERP_EMPLOYEE_PROPERTY_OUTRANGE;
		C2C_WW_LOG_ERR(iRetCode,"Property Out Range Error! Property:%s PropertyLimit:%s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
				oEmployee.GetEmployeePropertyInclude().to_string().c_str(),s_bitsetValidPropertyBit.to_string().c_str(),m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	return iRetCode;
}

